import {
  ApplicationRef,
  Component,
  ComponentFactoryResolver,
  ComponentRef, ElementRef,
  EmbeddedViewRef,
  Injector,
  OnInit, ViewChild
} from '@angular/core';
import { AlertComponent } from "../alert/alert.component";
import { fromEvent, interval, map, Observable } from "rxjs";
import { CommentService } from '../../../services/Comments.service';
import { AdBannerComponent } from '../AdBanner.component';
import { AdItem } from '../../base/hero.base';
import { AdService } from '../../base/base.service';

@Component({
  selector: 'app-alert-box',
  standalone: true,
  imports: [AlertComponent, AdBannerComponent],
  templateUrl: './alert-box.component.html',
  styleUrls: [], providers: [AdService]
})
export class AlertBoxComponent implements OnInit {
  @ViewChild("name")
  private component?: AlertComponent | undefined;
  private componentRef?: ComponentRef<AlertComponent>;
  private subscription?: any;
  @ViewChild('addBtn', { static: true }) addBtn?: ElementRef;
  @ViewChild('btn', { static: true }) btn?: ElementRef;

  private sub = interval(1000).subscribe(res => {
    // console.log('interval', res);
  });

  private handle2?: any;
  ads!: AdItem[];
  constructor(
    private cfr: ComponentFactoryResolver,
    private inject: Injector,
    private appRef: ApplicationRef,
    private commentService: CommentService, private adService: AdService
  ) {
    if (!this.component) {
      this.component = this.createContainer();
    }
  }

  showAlert() {
    // 判断是否已经创建组件
    if (!this.component) {
      this.component = this.createContainer();
    }
    // 传递所需参数
    this.component.setOptions({ content: '这是动态创建组件传入的内容', theme: 'success' })

    console.log(this.component)

  }

  ngOnInit(): void {
    // console.log(this.commentService.getComments());
    // this.newPromise();
    // this.newObservable();

    // this.newPromise2();
    // this.newObservable2();

    // this.newObservable2().subscribe(data => {})
    this.ads = this.adService.getAds();
    console.log(this.ads)
  }

  // 创建
  private createContainer(): AlertComponent {
    /**
     * 1.创建组件工厂：
     * constructor中注入ComponentFactoryResolver这个类
     * 创建指定类型的组件工厂（生产指定类型的组件）
     * */
    const factory = this.cfr.resolveComponentFactory<AlertComponent>(AlertComponent);
    /**
     * 2.工厂创建ComponentRef
     * constructor中注入Injector这个类
     * 根据指定的类型，创建组件的实例
     */
    this.componentRef = factory.create(this.inject);
    /**
     * constructor中注入ApplicationRef这个类
     * 3.将组件试图添加到视图树中，以激活变更检测
     * */
    this.appRef.attachView(this.componentRef.hostView);
    // 4.将组件到模版(包括app-alert标签)，添加到body最后(当然，可以添加到任何位置)
    document.body.appendChild((this.componentRef.hostView as EmbeddedViewRef<{}>).rootNodes[0] as HTMLElement);
    // 5.监听组件销毁事件
    this.componentRef.onDestroy(() => {
      console.log('component destory');
    });
    // 获取组件实例，相当于用@ViewChild获取子组件一样
    const { instance } = this.componentRef;
    // 6.监听组件的output事件
    // subscribe是rxjs的内容，以后会介绍
    instance.closed.subscribe(() => {
      if (this.componentRef) {
        this.componentRef.destroy();
      }
    });
    return instance;
  }

  newPromise(): Promise<any> {
    const p = new Promise(resolve => {
      console.log("initial a promise") // 立即触发
    });
    return p;

  }

  newObservable(): Observable<any> {
    const o = new Observable(subscriber => {
      console.log('initial a newObservable'); // 不触发
    });
    return o;
  }

  newPromise2(): Promise<any> {
    const p = new Promise(resolve => {
      resolve(['a', 'b', 'c']);
    }).then(res => {
      console.log('第一个then');
      return res;
    }).then(res => {
      console.log('第2个then');
      return res;
    }); // 打印出结果，被解析时自动完成
    return p;
  }

  newObservable2(): Observable<any> {
    const o = new Observable(subscriber => {
      console.log('initial a newObservable');
      subscriber.next(['a', 'b', 'c']);
    }).pipe(
      map(res => {
        console.log('第一个map');
        return res;
      }),
      map(res => {
        console.log('第2个map');
        return res;
      })
    );  // 不能打印出结果，不订阅，pipe中的所有函数都不会触发
    return o;
  }

  cancelObservable() {
    this.sub.unsubscribe();
  }

  doCreateBind() {
    console.log("12312312312312")
    let handler = function handler(e: any) {
      console.log('Clicked e = ', e);
    }
    // 创建点击事件
    const clicks$ = fromEvent(this.addBtn?.nativeElement, 'click');
    // 处理逻辑
    this.subscription = clicks$.subscribe(e => {
      console.log('handler', handler);
      handler('12312321');
    })
      ;

  }

  doCancelBind() {
    // 取消订阅
    this.subscription.unsubscribe();
  }


  cancelEvent() {
    this.btn?.nativeElement?.removeEventListener('click', this.handle2);
  }

  addEvent() {
    this.handle2 = function handler(e: any) {
      console.log('事件api Clicked e = ', e);
    }
    this.btn?.nativeElement?.addEventListener('click', this.handle2);
  }
}
